﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.Serialization;

namespace Skywave.Windows.Forms
{
    [Serializable]
    public partial class MarkReaderCode : UserControl, IPrintOn, ISerializable
    {
        public MarkReaderCode()
        {
            InitializeComponent();
        }
        private string _Code = "0123456789";
        /// <summary>
        /// Code Property
        /// </summary>
        [Category("MarkReaderCode")]
        public string Code
        {
            get { return _Code; }
            set { _Code = value; Invalidate(); }
        }

        private float _VerticalDistanceBetweenMarks = 7.7F;
        /// <summary>
        /// VerticalDistanceBetweenMarks Property
        /// </summary>
        [Category("MarkReaderCode")]
        public float VerticalDistanceBetweenMarks
        {
            get { return _VerticalDistanceBetweenMarks; }
            set { _VerticalDistanceBetweenMarks = value; Invalidate(); }
        }

        private float _HorizontalDistanceBetweenMarks = 4.5F;
        /// <summary>
        /// HorizontalDistanceBetweenMarks Property
        /// </summary>
        [Category("MarkReaderCode")]
        public float HorizontalDistanceBetweenMarks
        {
            get { return _HorizontalDistanceBetweenMarks; }
            set { _HorizontalDistanceBetweenMarks = value; Invalidate(); }
        }

        private float _MarkWidth = 19F;
        /// <summary>
        /// MarkWidth Property
        /// </summary>
        [Category("MarkReaderCode")]
        public float MarkWidth
        {
            get { return _MarkWidth; }
            set { _MarkWidth = value; Invalidate(); }
        }

        private float _MarkHeight = 8F;
        /// <summary>
        /// MarkHeight Property
        /// </summary>
        [Category("MarkReaderCode")]
        public float MarkHeight
        {
            get { return _MarkHeight; }
            set { _MarkHeight = value; Invalidate(); }
        }

        private float _CodeHeight = 25F;
        /// <summary>
        /// CodeHeight Property
        /// </summary>
        [Category("MarkReaderCode")]
        public float CodeHeight
        {
            get { return _CodeHeight; }
            set { _CodeHeight = value; Invalidate(); }
        }

        private int _CodeLength = 12;
        /// <summary>
        /// CodeLength Property
        /// </summary>
        [Category("MarkReaderCode")]
        public int CodeLength
        {
            get { return _CodeLength; }
            set { _CodeLength = value; Invalidate(); }
        }

        #region IPrintOn Members

        public void PrintOn(Graphics g, Rectangle bounds)
        {
            string str1, str2;
            StringFormat sf1;

            sf1 = new StringFormat();
            sf1.SetDigitSubstitution(new System.Globalization.CultureInfo("fa-IR").LCID, StringDigitSubstitute.National);
            sf1.LineAlignment = StringAlignment.Center;
            sf1.Alignment = StringAlignment.Center;
            str1 = _Code;
            while (str1.Length < _CodeLength)
                str1 = "0" + str1;
            RectangleF rect1;
            SolidBrush brush1 = new SolidBrush(ForeColor);
            for (int j = 0; j < str1.Length ; j++)
            {
                str2 = str1.Substring(j, 1);
                //Code String
                rect1 = new RectangleF(
                    (bounds.X + j * (_HorizontalDistanceBetweenMarks + _MarkWidth)),
                    bounds.Y,
                    _MarkWidth,
                    _CodeHeight);
                g.DrawString(str2, Font, brush1, rect1, sf1);
                //Mark
                rect1 = new RectangleF(
                    (bounds.X + j * (_HorizontalDistanceBetweenMarks + _MarkWidth)),
                    (bounds.Y + _CodeHeight + int.Parse(str2) * (_VerticalDistanceBetweenMarks + _MarkHeight)),
                    _MarkWidth,
                    _MarkHeight);
                g.FillRectangle(brush1, rect1);
            }
        }

        #endregion

        //public override bool Equals(object obj)
        //{
        //    if (obj is MarkReaderCode)
        //        return Code.Equals((obj as MarkReaderCode).Code);
        //    else
        //        return false;
        //}

        #region Serialization

        public MarkReaderCode(SerializationInfo info, StreamingContext context)
        {
            InitializeComponent();

            _Code = info.GetString("Code");
            _CodeHeight = info.GetSingle("CodeHeight");
            _HorizontalDistanceBetweenMarks = info.GetSingle("HorizontalDistanceBetweenMarks");
            _MarkHeight = info.GetSingle("MarkHeight");
            _MarkWidth = info.GetSingle("MarkWidth");
            _VerticalDistanceBetweenMarks = info.GetSingle("VerticalDistanceBetweenMarks");
            _CodeLength = info.GetInt32("CodeLength");
        }

        public void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("Code", _Code);
            info.AddValue("CodeHeight", _CodeHeight);
            info.AddValue("HorizontalDistanceBetweenMarks", _HorizontalDistanceBetweenMarks);
            info.AddValue("MarkHeight", _MarkHeight);
            info.AddValue("MarkWidth", _MarkWidth);
            info.AddValue("VerticalDistanceBetweenMarks", _VerticalDistanceBetweenMarks);
            info.AddValue("CodeLength", _CodeLength);
        }

        #endregion

        private void MarkReaderCode_Paint(object sender, PaintEventArgs e)
        {
            PrintOn(e.Graphics, Bounds);
        }
    }
}
